﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace iMon.DisplayApi
{
    public static class iMonNativeApi
    {
        #region Enumerations

        /// <summary>
        /// These enumeration values represent display type.
        /// Currently iMON Display API supports VFD and LCD products.
        /// </summary>
        public enum iMonDisplayType
        {
            /// <summary>
            /// Unknown product
            /// </summary>
            None = 0,
            /// <summary>
            /// VFD product
            /// </summary>
            VFD = 0x01,
            /// <summary>
            /// LCD product
            /// </summary>
            LCD = 0x02,
        }

        /// <summary>
        /// These enumeration values represent the returned result for iMON Display API function calls.
        /// All iMON Display API function calls return one of this result values.
        /// For meaning of each result, refer the comment of each line below
        /// </summary>
        public enum iMonDisplayResult : int
        {
            // errors
            /// <summary>
            /// Function Call Succeeded Without Error
            /// </summary>
            Succeeded = 0,
            /// <summary>
            /// Unspecified Failure
            /// </summary>
            Failed,
            /// <summary>
            /// Failed to Allocate Necessary Memory
            /// </summary>
            OutOfMemory,
            /// <summary>
            /// One or More Arguments Are Not Valid
            /// </summary>
            InvalidArguments,
            /// <summary>
            /// API is Not Initialized
            /// </summary>
            NotInitialized,
            /// <summary>
            /// Pointer is Not Valid
            /// </summary>
            InvalidPointer,

            // status 
            /// <summary>
            /// API is Initialized
            /// </summary>
            ApiInitialized = 0x1000,
            /// <summary>
            /// API is Not Initialized
            /// </summary>
            ApiNotInitialized,
            /// <summary>
            /// API Can Control iMON Display (Display Plug-in Mode)
            /// </summary>
            ApiInPluginMode,
            /// <summary>
            /// API Can't Control iMON Display
            /// </summary>
            ApiNotInPluginMode
        }

        /// <summary>
        /// These enumeration values represent the notification codes.
        /// iMON Display API will send or post message to the caller application.
        /// The caller application should assign the message and the winodw handle to receivce message with IMON_Display_Init fucntion.
        /// These enumeration values are used with WPARAM parameter of the message.
        /// </summary>
        public enum iMonDisplayNotifyCode : int
        {
            /// <summary>
            /// When API succeeds to get the control for the display, API will post caller-specified message with DSPNM_PLUGIN_SUCCEED as WPARAM parameter.
            /// LPARAM represents DSPType. This value can be 0x01 (VFD), 0x02 (LCD) or 0x03 (VFD+LCD).
            /// </summary>
            PluginSuccess = 0,

            /// <summary>
            /// When API fails to get the control for the display, API will post caller-specified message with DSPNM_PLUGIN_FAILED as WPARAM parameter.
            /// LPARAM represents error code with DSPNResult.
            /// </summary>
            PluginFailed,

            /// <summary>
            /// When iMON starts, API will post caller-specified message with DSPNM_IMON_RESTARTED as WPARAM parameter.\n
            /// LPARAM represents DSPType. This value can be 0 (No Display), 0x01 (VFD), 0x02 (LCD) or 0x03 (VFD+LCD).
            /// </summary>
            iMonRestarted,

            /// <summary>
            /// When iMON closed, API will post caller-specified message with DSPNM_IMON_CLOSED as WPARAM parameter.\n
            /// LPARAM is not used.
            /// </summary>
            iMonClosed,

            /// <summary>
            /// When iMON HW newly connected, API will post caller-specified message with DSPNM_HW_CONNECTED as WPARAM parameter.\n
            /// LPARAM represents DSPType. This value can be 0 (No Display), 0x01 (VFD), 0x02 (LCD) or 0x03 (VFD+LCD).
            /// </summary>
            HardwareConnected,

            /// <summary>
            /// When iMON HW disconnected, API will post caller-specified message with DSPNM_HW_DISCONNECTED as WPARAM parameter.\n
            /// LPARAM is DSPNResult value, DSPN_ERR_HW_DISCONNECTED.
            /// </summary>
            HardwareDisconnected,

            /// <summary>
            /// When iMON LCD finishes scrolling Text, API will post caller-specified message with DSPNM_LCD_TEXT_SCROLL_DONE as WPARAM parameter.\n
            /// The caller application may need to know when text scroll is finished, for sending next text.\n
            /// LPARAM is not used.
            /// </summary>
            LCDTextScrollDone = 0x1000
        }

        /// <summary>
        /// These enumeration values represent the result status for requesting Display Plug-in Mode to iMON.
        /// iMON Display API notifies one of this result values to the caller application after requesting Display Plug-in Mode to iMON.
        /// For more information, refer the comment of each line below
        /// </summary>
        public enum iMonDisplayInitResult : int
        {
            /// <summary>
            /// Display Plug-in Mode is Initialized Successfully
            /// </summary>
            Succeeded = 0,
            /// <summary>
            /// Display Plug-in is Already Used by Other Application
            /// </summary>
            PluginModeAlreadyInUse = 0x0100,
            /// <summary>
            /// iMON HW is Not Connected
            /// </summary>
            HardwareNotConnected,
            /// <summary>
            /// The Connected iMON HW doesn't Support Display Plug-in
            /// </summary>
            HardwareNotSupported,
            /// <summary>
            /// Display Plug-in Mode Option is Disabled
            /// </summary>
            PluginModeDisabled,
            /// <summary>
            /// The Latest iMON is Not Installed or iMON Not Running
            /// </summary>
            iMonNotResponding,
            /// <summary>
            /// Unknown Failure
            /// </summary>
            Unknown = 0x0200
        }

        #endregion

        #region icons

        /// <summary>
        /// Sound LCD Icons
        /// </summary>
        [Flags]
        public enum SoundLcdIcons
        {
            /// <summary>
            /// Sound uses the SPDIF output.
            /// </summary>
            SpeakerSPDIF = 0x01,
            /// <summary>
            /// A sound box on the left rear is in use.
            /// </summary>
            SpeakerRearLeft = 0x02,
            /// <summary>
            /// A sound box on the right side is in use.
            /// </summary>
            SpeakerSideRight = 0x04,
            /// <summary>
            /// 
            /// </summary>
            SpeakerLFE = 0x08,
            /// <summary>
            /// A sound box on the left side is in use.
            /// </summary>
            SpeakerSideLeft = 0x10,
            /// <summary>
            /// A sound box on the right front is in use.
            /// </summary>
            SpeakerFrontRight = 0x20,
            /// <summary>
            /// A sound box on the center front is in use.
            /// </summary>
            SpeakerCenter = 0x40,
            /// <summary>
            /// A sound box on the left front is in use.
            /// </summary>
            SpeakerFrontLeft = 0x80,
            /// <summary>
            /// A sound box on the right rear is in use.
            /// </summary>
            SpeakerRearRight = 0x8000
        }


        /// <summary>
        /// Disc Lcd Icons
        /// </summary>
        [Flags]
        public enum DiscLcdIcons
        {
            /// <summary>
            /// 
            /// </summary>
            DiscTopRight = 0x01,
            /// <summary>
            /// 
            /// </summary>
            DiscMiddleRight = 0x02,
            /// <summary>
            /// 
            /// </summary>
            DiscBottomRight = 0x04,
            /// <summary>
            /// 
            /// </summary>
            DiscBottomCenter = 0x08,
            /// <summary>
            /// 
            /// </summary>
            DiscBottomLeft = 0x10,
            /// <summary>
            /// 
            /// </summary>
            DiscMiddleLeft = 0x20,
            /// <summary>
            /// 
            /// </summary>
            DiscTopLeft = 0x40,
            /// <summary>
            /// 
            /// </summary>
            DiscTopCenter = 0x80,
            /// <summary>
            /// 
            /// </summary>
            DiscCircle = 0x8000

        }

        /// <summary>
        /// Media Type Icons
        /// </summary>
        [Flags]
        public enum MediaTypeLcdIcons
        {
            /// <summary>
            /// 
            /// </summary>
            NewsWeather = 0x02,
            /// <summary>
            /// 
            /// </summary>
            Webcast = 0x04,
            /// <summary>
            /// 
            /// </summary>
            Tv = 0x08,
            /// <summary>
            /// 
            /// </summary>
            CdDvd = 0x10,
            /// <summary>
            /// 
            /// </summary>
            Photo = 0x20,
            /// <summary>
            /// 
            /// </summary>
            Movie = 0x40,
            /// <summary>
            /// 
            /// </summary>
            Music = 0x80
        }

        /// <summary>
        /// Video Codec Icons
        /// </summary>
        [Flags]
        public enum VideoCodecLcdIcons
        {
            /// <summary>
            /// 
            /// </summary>
            VideoWMA = 0x01,
            /// <summary>
            /// 
            /// </summary>
            VideoDTS = 0x02,
            /// <summary>
            /// 
            /// </summary>
            VideoAC3 = 0x04,
            /// <summary>
            /// 
            /// </summary>
            VideoMPGAudio = 0x08,
            /// <summary>
            /// 
            /// </summary>
            VideoWMV = 0x10,
            /// <summary>
            /// 
            /// </summary>
            VideoXviD = 0x20,
            /// <summary>
            /// 
            /// </summary>
            VideoDivX = 0x40,
            /// <summary>
            /// 
            /// </summary>
            VideoMPG = 0x80
        }


        /// <summary>
        /// Audio codec Icons
        /// </summary>
        [Flags]
        public enum AudioCodecLcdIcons
        {
            /// <summary>
            /// 
            /// </summary>
            AudioOGG = 0x40,
            /// <summary>
            /// 
            /// </summary>
            AudioMP3 = 0x80,
            /// <summary>
            /// 
            /// </summary>
            AudioWMA = 0x20,
            /// <summary>
            /// 
            /// </summary>
            AudioWAV = 0x10
        }

        /// <summary>
        /// Aspect Ratio Icons
        /// </summary>
        [Flags]
        public enum AspectRatioLcdIcons
        {
            /// <summary>
            /// 
            /// </summary>
            AspectRatioScreen2 = 0x04,
            /// <summary>
            /// 
            /// </summary>
            AspectRatioScreen1 = 0x08,
            /// <summary>
            /// 
            /// </summary>
            AspectRatioHDTV = 0x10,
            /// <summary>
            /// 
            /// </summary>
            AspectRatioTv = 0x20,
            /// <summary>
            /// 
            /// </summary>
            AspectRatioFIT = 0x40,
            /// <summary>
            /// 
            /// </summary>
            AspectRatioSource = 0x80
        }


        /// <summary>
        /// Other Icons
        /// </summary>
        [Flags]
        public enum OtherLcdIcons
        {
            /// <summary>
            /// 
            /// </summary>
            Time = 0x04,
            /// <summary>
            /// 
            /// </summary>
            Volume = 0x08,
            /// <summary>
            /// Recording is active.
            /// </summary>
            Recording = 0x10,
            /// <summary>
            /// 
            /// </summary>
            Alarm = 0x20,
            /// <summary>
            /// Shuffle is active for the current playlist.
            /// </summary>
            Shuffle = 0x40,
            /// <summary>
            /// 
            /// </summary>
            Repeat = 0x80
        }

        #endregion

        #region structures
        /// <summary>
        /// This structure contains Equalizer data for 16 bands.
        /// </summary>
        [StructLayout(LayoutKind.Sequential), Serializable]
        public struct iMonDisplayEqualizerData
        {
            /// <summary>
            /// Represents Equalizer data for 16 bands. Its range is from 0 to 100.
            /// </summary>
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public int[] BandData;
        }
        #endregion

        #region iMon API functions
        /// <summary>
        /// This function should be called to use other functions in iMON Display API.
        /// When the caller application calls this function, API tries to request Display Plug-in Mode to iMON.
        /// </summary>
        /// <param name="hwndNoti">API will send/post message to this handle.</param>
        /// <param name="uMsgNotification">API will send/post message to hwndNoti with this message identifier.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.InvalidArguments or DisplayResult.OutOfMemory can be returned when error occurs.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_Init")]
        public static extern iMonDisplayResult IMON_Display_Init(IntPtr hwndNoti, uint uMsgNotification);

        /// <summary>
        /// This function should be called when the caller application need not use this API any more.
        /// If this function call is missed, iMON can't display other information.
        /// </summary>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_Uninit")]
        public static extern iMonDisplayResult IMON_Display_Uninit();

        /// <summary>
        /// This function can be used when the caller application wants to know if API is initialized.
        /// </summary>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// If API is initialized, this call will return DisplayResult.Initialized. Otherwise DisplayResult.ApiNotInitialized will be returned.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_IsInited")]
        public static extern iMonDisplayResult IMON_Display_IsInited();

        /// <summary>
        /// This function can be used when the caller application wants to know if API can control iMON display.
        /// </summary>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// If API can control iMON display, this call will return DisplayResult.InPluginMode. Otherwise DisplayResult.NotInPluginMode will be returned.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_IsPluginModeEnabled")]
        public static extern iMonDisplayResult IMON_Display_IsPluginModeEnabled();

        /// <summary>
        /// This function can be used when the caller application wants to display text data on VFD module.
        /// </summary>
        /// <param name="line1">This string data will be displayed on the 1st line of VFD module.
        /// It doesn't support multi-byte character and if string data is longer than 16 characters, it displays 16 characters from the first.</param>
        /// <param name="line2">This string data will be displayed on the 2nd line of VFD module.
        /// It doesn't support multi-byte character and if string data is longer than 16 characters, it displays 16 characters from the first.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.InvalidPointer, DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetVfdText", CharSet = CharSet.Auto)]
        public static extern iMonDisplayResult IMON_Display_SetVfdText(string line1, string line2);

        /// <summary>
        /// This function can be used when the caller application wants to display equalizer data on VFD module.
        /// </summary>
        /// <param name="pEqData">Pointer of DisplayEqualizerData structure. The caller application should fill this structure with the equalizer data for 16 bands.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.InvalidPointer, DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetVfdEqData")]
        public static extern iMonDisplayResult IMON_Display_SetVfdEqData(ref iMonDisplayEqualizerData pEqData);

        /// <summary>
        /// This function can be used when the caller application wants to display text data on LCD module.
        /// </summary>
        /// <param name="line">This string data will be displayed on the LCD module.
        /// It supports multi-byte character and if string data is longer than display area, it will start to scroll.
        /// When text scrolling is finished, API will notify it with DisplayNotifyCode enumeration value, DisplayNotifyCode.LCDTextScrollDone.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.InvalidPointer, DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdText", CharSet = CharSet.Auto)]
        public static extern iMonDisplayResult IMON_Display_SetLcdText(string line);

        /// <summary>
        /// This function can be used when the caller application wants to display equalizer data on LCD module.
        /// </summary>
        /// <param name="pEqDataL">Pointer of DisplayEqualizerData structure. This parameter represents equalizer data of left channel.
        /// The caller application should fill this structure with the equalizer data of left channel for 16 bands.</param>
        /// <param name="pEqDataR">Pointer of DisplayEqualizerData structure. This parameter represents equalizer data of right channel.
        /// The caller application should fill this structure with the equalizer data of right channel for 16 bands.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.InvalidPointer, DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdEqData")]
        public static extern iMonDisplayResult IMON_Display_SetLcdEqData(ref iMonDisplayEqualizerData pEqDataL, ref iMonDisplayEqualizerData pEqDataR);

        /// <summary>
        /// This function can be used when the caller application wants to turn on/off all icons on LCD module.
        /// </summary>
        /// <param name="bOn">If this value is TRUE, iMON will turn on all icons. Otherwise, iMON will turn off all icons.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdAllIcons")]
        public static extern iMonDisplayResult IMON_Display_SetLcdAllIcons(bool bOn);

        /// <summary>
        /// This function can be used when the caller application wants to turn on/off orange shaped disk icons on the upper left part of LCD module.
        /// Disk icons consist of 8 pieces of orange and orange peel.
        /// </summary>
        /// <param name="btIconData1">Each bit represents one of icons shaped the piece of orange.
        /// MSB is used for the piece placed on top and the remaining bits are for the piece placed in CCW from top.</param>
        /// <param name="btIconData2">MSB represents the orange peel shaped icon. Other bits are not used.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdOrangeIcon")]
        public static extern iMonDisplayResult IMON_Display_SetLcdOrangeIcon(byte btIconData1, byte btIconData2);

        /// <summary>
        /// This function can be used when the caller application wants to turn on/off media type icons on the upper part of LCD module.
        /// </summary>
        /// <param name="btIconData">Each bit represents one of media type icons. From MSB each bit represents MUSIC, MOVIE, PHOTO, CD/DVD, TV, WEBCASTING and NEWS/WEATHER icon.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdMediaTypeIcon")]
        public static extern iMonDisplayResult IMON_Display_SetLcdMediaTypeIcon(byte btIconData);

        /// <summary>
        /// This function can be used when the caller application wants to turn on/off speaker icons on the upper right part of LCD module.
        /// </summary>
        /// <param name="btIconData1">Each bit represents one of speaker icons.\nFrom MSB each bit represents L, C, R, SL, LFE, SR, RL and SPDIF icon.</param>
        /// <param name="btIconData2">MSB represents RR icon. Other bits are not used.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdSpeakerIcon")]
        public static extern iMonDisplayResult IMON_Display_SetLcdSpeakerIcon(byte btIconData1, byte btIconData2);

        /// <summary>
        /// This function can be used when the caller application wants to turn on/off codec icons for video file on the lower part of LCD module.
        /// </summary>
        /// <param name="btIconData">Each bit represents one of video codec icons. From MSB each bit represents MPG, DIVX, XVID, WMV, MPG, AC3, DTS and WMA icon.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdVideoCodecIcon")]
        public static extern iMonDisplayResult IMON_Display_SetLcdVideoCodecIcon(byte btIconData);

        /// <summary>
        /// This function can be used when the caller application wants to turn on/off codec icons for audio file on the lower part of LCD module.
        /// </summary>
        /// <param name="btIconData">Each bit represents one of audio codec icons. From MSB each bit represents MP3, OGG, WMA and WAV icon.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdAudioCodecIcon")]
        public static extern iMonDisplayResult IMON_Display_SetLcdAudioCodecIcon(byte btIconData);

        /// <summary>
        /// This function can be used when the caller application wants to turn on/off aspect ratio icons on the lower right part of LCD module.
        /// </summary>
        /// <param name="btIconData">Each bit represents one of aspect ratio icons. From MSB each bit represents SRC, FIT, TV, HDTV, SCR1 and SCR2 icon.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdAspectRatioIcon")]
        public static extern iMonDisplayResult IMON_Display_SetLcdAspectRatioIcon(byte btIconData);

        /// <summary>
        /// This function can be used when the caller application wants to turn on/off icons on the lower left part of LCD module.
        /// </summary>
        /// <param name="btIconData">Each bit represents icon. From MSB each bit represents REPEAT, SHUFFLE, ALARM, REC, VOL and TIME icon.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdEtcIcon")]
        public static extern iMonDisplayResult IMON_Display_SetLcdEtcIcon(byte btIconData);

        /// <summary>
        /// This function can be used when the caller application wants to display progress bar on the upper and lower left part of text area of LCD module.
        /// </summary>
        /// <param name="nCurPos">It represents the current position of progress bar.</param>
        /// <param name="nTotal">It represents the total length of progress bar.</param>
        /// <returns>This function will return one of DisplayResult enumeration value.
        /// DisplayResult.Succeeded will be returned if succeeded. DisplayResult.NotInitialized or DisplayResult.Failed can be returned if failed.</returns>
        [DllImport("iMONDisplay.dll", EntryPoint = "IMON_Display_SetLcdProgress")]
        public static extern iMonDisplayResult IMON_Display_SetLcdProgress(int nCurPos, int nTotal);
        #endregion

    }
}
